package com.ht.demo.service.manager.system.impl;

import com.ht.demo.common.appexception.AppErrorCodeEnum;
import com.ht.demo.common.appexception.AppException;
import com.ht.demo.common.appexception.ResultData;
import com.ht.demo.common.page.PageBO;
import com.ht.demo.common.pojo.bo.system.SysRoleBO;
import com.ht.demo.common.pojo.bo.system.SysUserBO;
import com.ht.demo.common.pojo.bo.system.SysUserRoleBO;
import com.ht.demo.common.pojo.qto.system.SysUserQTO;
import com.ht.demo.common.util.MD5Util;
import com.ht.demo.dao.dao.system.SysRoleDao;
import com.ht.demo.dao.dao.system.SysUserDao;
import com.ht.demo.dao.dao.system.SysUserRoleDao;
import com.ht.demo.dao.domain.system.SysDeptDO;
import com.ht.demo.dao.domain.system.SysUserDO;
import com.ht.demo.dao.domain.system.SysUserRoleDO;
import com.ht.demo.service.constans.SystemConfig;
import com.ht.demo.common.constans.SystemConstant;
import com.ht.demo.service.convert.system.SysRoleBeanUtil;
import com.ht.demo.service.convert.system.SysUserBeanUtil;
import com.ht.demo.service.manager.system.SysRoleMenuManager;
import com.ht.demo.service.manager.system.SysUserManager;
import com.ht.demo.service.manager.system.SysUserRoleManager;
import com.ht.demo.service.mapper.system.SysDeptMapper;
import com.ht.demo.service.mapper.system.SysUserMapper;
import com.ht.demo.service.mapper.system.SysUserPostMapper;
import com.ht.demo.service.system.UserTokenManager;
import com.ht.demo.service.util.ServletUtils;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.Set;

@Component
public class SysUserManagerImpl implements SysUserManager {
    @Resource
    private SysUserMapper sysUserMapper;
    @Resource
    private SysUserDao sysUserDao;
    @Resource
    private UserTokenManager userTokenManager;
    @Resource
    private SysRoleDao sysRoleDao;
    @Resource
    private SysUserRoleDao sysUserRoleDao;
    @Resource
    private SysRoleMenuManager sysRoleMenuManager;
    @Autowired
    private SysUserRoleManager userRoleManager;
    @Resource
    private SysDeptMapper sysDeptMapper;
    @Resource
    private SysUserPostMapper sysUserPostMapper;

    @Transactional(rollbackFor = Exception.class)
    @Override
    public SysUserBO insertUser(SysUserBO userBO) throws AppException {
        SysUserBeanUtil.saveCheckParam(userBO);
        SysUserDO countDO = new SysUserDO();
        countDO.setLoginNo(userBO.getLoginNo());
        if (sysUserMapper.countByCondition(countDO) > 0) {
            throw new AppException(AppErrorCodeEnum.LOGIN_NO_EXISTS);
        }
        userBO.setPassWdMd(MD5Util.passwordMD5(userBO.getPassWd(), SystemConfig.passwordMd5Key));
        SysDeptDO dept = sysDeptMapper.getById(userBO.getSysDeptId());
        if (dept != null) {
            userBO.setDeptName(dept.getDeptName());
        }

        userBO.setCreateTime(new Date());
        SysUserDO userDO = SysUserBeanUtil.sysUserBOToDO(userBO);
        sysUserMapper.insertSysUser(userDO);

        SysUserRoleBO userRole = new SysUserRoleBO();
        userRole.setSysUserId(userDO.getId());
        userRole.setSysRoleId(userBO.getSysRoleId());
        userRoleManager.addUserRoleRelation(userRole);
        if (CollectionUtils.isNotEmpty(userBO.getSysPostIds())) {
            sysUserPostMapper.savaUserPostRelation(userDO.getId(), userBO.getSysPostIds());
        }

        return userBO;
    }

    @Override
    public Boolean updateUser(SysUserBO userBO) throws AppException {
        if (userBO == null || userBO.getSysUserId() == null) {
            throw new AppException(AppErrorCodeEnum.PARAMETER_ERROR);
        }
        SysUserDO old = sysUserMapper.getById(userBO.getSysUserId());
        if (old == null) {
            throw new AppException(AppErrorCodeEnum.UPDATE_DATE_NOT_EXISTS);
        }
        if (StringUtils.isNotBlank(userBO.getPassWd()) && !old.getPassWd().equals(userBO.getPassWd())) {
            userBO.setPassWdMd(MD5Util.passwordMD5(userBO.getPassWd(), SystemConfig.passwordMd5Key));
        }
        //是否修改登录账号
        if (StringUtils.isNotBlank(userBO.getLoginNo()) && !userBO.getLoginNo().equals(old.getLoginNo())) {
            SysUserDO countDO = new SysUserDO();
            countDO.setLoginNo(userBO.getLoginNo());
            if (sysUserMapper.countByCondition(countDO) > 0) {
                throw new AppException(AppErrorCodeEnum.LOGIN_NO_EXISTS);
            }
        }
        //是否修改角色且不可修改超级管理员的角色
        if (!SysUserBO.isAdmin(userBO.getSysUserId())) {
            SysUserRoleDO userRoleDO = sysUserRoleDao.findByUserId(userBO.getSysUserId());
            if (userRoleDO != null && userBO.getSysRoleId() != null && userRoleDO.getSysRoleId().longValue() != userBO.getSysRoleId().longValue()) {
                SysUserRoleBO relation = new SysUserRoleBO();
                relation.setSysUserId(userBO.getSysUserId());
                relation.setSysRoleId(userBO.getSysRoleId());
                userRoleManager.addUserRoleRelation(relation);
            }
        }

        if (userBO.getSysDeptId() != null && !userBO.getSysDeptId().equals(old.getSysDeptId())) {
            SysDeptDO dept = sysDeptMapper.getById(userBO.getSysDeptId());
            if (dept != null) {
                userBO.setDeptName(dept.getDeptName());
            }
        }

        sysUserMapper.updateSysUserById(SysUserBeanUtil.sysUserBOToDO(userBO));
        if (CollectionUtils.isNotEmpty(userBO.getSysPostIds())) {
            sysUserPostMapper.savaUserPostRelation(userBO.getSysUserId(), userBO.getSysPostIds());
        }
        return Boolean.TRUE;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean deleteUser(Long sysUserId) throws AppException {
        sysUserRoleDao.deleteByUserId(sysUserId);
        sysUserMapper.removeById(sysUserId);
        return Boolean.TRUE;
    }

    @Override
    public SysUserBO findByUserId(Long sysUserId) throws AppException {
        SysUserBO data = SysUserBeanUtil.sysUserDOToBO(sysUserMapper.getById(sysUserId));
        SysUserRoleDO userRoleDO = sysUserRoleDao.findByUserId(sysUserId);
        data.setSysRoleId(userRoleDO != null ? userRoleDO.getSysRoleId() : null);
        List<Long> postIds = sysUserPostMapper.getPostIds(sysUserId);
        data.setSysPostIds(postIds);
        return data;
    }
    @Override
    public PageBO<SysUserBO> findUserForPage(SysUserQTO qto) throws AppException {
        PageBO<SysUserBO> pageBO = new PageBO<>();
        if (qto == null) {
            return pageBO;
        }
        Integer count = sysUserDao.findForPageCount(qto);
        if (count == null || count <= 0) {
            return pageBO;
        }

        List<SysUserBO> boList = SysUserBeanUtil.doList2BOList(sysUserDao.findForPage(qto));
        pageBO.setTotal(count);
        pageBO.setData(boList);

        return pageBO;
    }

    @Override
    public ResultData getInfo() throws AppException {
        String token = ServletUtils.getRequest().getHeader(SystemConstant.TOKEN_NAME);
        SysUserBO loginUser = userTokenManager.getLoginUser(token);
        SysUserRoleDO userRoleDO = sysUserRoleDao.findByUserId(loginUser.getSysUserId());

        SysRoleBO role = SysRoleBeanUtil.sysRoleDOToBO(sysRoleDao.findById(userRoleDO.getSysRoleId()));
        Set<String> permSet = sysRoleMenuManager.getPermission(role.getSysRoleId());

        ResultData result = new ResultData();
        result.success();
        result.getExtraMap().put("user", loginUser);
        result.getExtraMap().put("roles", role);
        result.getExtraMap().put("permissions", permSet);

        return result;
    }
}
